package servidor.mundo.basesdedatos;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import servidor.mundo.entidades.Estadistica;
import servidor.mundo.entidades.Examen;
import servidor.mundo.entidades.Pregunta;

public class MySQL implements IBD 
{
	private Connection conn;
	
	public MySQL( String user, String pass, String dburl ) throws BDException 
	{
        try
        {
            String url = "jdbc:mysql://"+ dburl+"?autoReconnect=true";
            Class.forName("com.mysql.jdbc.Driver").newInstance( );
            conn = DriverManager.getConnection( url, user, pass );
        }
        catch(ClassNotFoundException e)
        {
            throw new BDException("No se encontro el driver de la base de datos!!!");
        }
        catch(Exception e)
        {
        	e.printStackTrace();
            throw new BDException("No se pudo conectar a la base de datos");
        }

	}

	private ResultSet consulta(String consulta) throws BDException 
	{
		Statement s;
		try {
			s = conn.createStatement();
			s.executeQuery( consulta );
			return s.getResultSet( );
		} catch (SQLException e) {
			e.printStackTrace();
			throw new BDException( "Error haciendo consulta: " + e.getMessage() );
		}
	}	

	private void transaccion(ArrayList<String> transacciones) throws BDException 
	{
		Statement s;
		try {
			s = conn.createStatement();
			conn.setAutoCommit(false);
			for( String str : transacciones )
				s.executeUpdate( str );
			conn.commit();
		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
			}
			throw new BDException( "Error haciendo transaccion: " + e.getMessage() );
		}
	}

	@Override
	public Estadistica darEstadisticas( String nombre ) throws BDException 
	{
		final String consulta = "SELECT avg( r.general ) , avg( r.tiempo ) , a.nombre, avg( ra.puntaje ) " +
								"FROM Resultado r NATURAL JOIN Res_Area ra NATURAL JOIN Area a " +
								"WHERE r.ID_EXAMEN=(SELECT ID_EXAMEN FROM Examen WHERE nombre='" + nombre + "')" +
								"GROUP BY ra.ID_AREA";
		
		try {
			Estadistica e = new Estadistica( );
			
			ResultSet rs = consulta( consulta );
			
			if( !rs.next() )
				throw new BDException( "No hay resultados" );
			
			e.setGeneral( rs.getInt(1) );
			e.setTiempo( rs.getInt(2) );
						
			while( rs.next() )
				e.addArea( rs.getString(3) + ":" + rs.getDouble(4) );
			
			return e;
		} catch (SQLException e) {
			throw new BDException( e.getMessage() );
		}
	}

	@Override
	public Examen darExamen(String examen) throws BDException {
		final String consulta1 = "SELECT ID_EXAMEN, codigo, descripcion FROM Examen WHERE nombre='"+ examen +"'";

		try {
			Examen e = new Examen( );
			
			ResultSet rs = consulta( consulta1 );
			
			if( !rs.next() )
				throw new BDException( "No hay examen con ese nombre" );
			
			e.setCodigo( rs.getString(2) );
			e.setDescripcion( rs.getString(3) );
			
			int id = rs.getInt(1);
			
			rs = consulta( "SELECT tipo, p.enunciado, imagen, opciones, respuesta, nombre as area FROM Pregunta p NATURAL JOIN Area a WHERE ID_EXAMEN=" + id );
			
			while( rs.next() )
			{
				Pregunta p = new Pregunta( );
				p.setArea(rs.getString(6));
				p.setEnunciado(rs.getString(2));
				p.setImagen(rs.getString(3));
				p.setRespuesta(rs.getString(5));
				p.setTipo(rs.getInt(1)+"");
				p.setOpciones( rs.getString(4).split("#@#") );
				e.addPregunta( p );
			}
			return e;
		} catch (SQLException e) {
			throw new BDException( e.getMessage() );
		}
	}

	@Override
	public void registrarResultados(Estadistica e) throws BDException {
		ArrayList<String> trans = new ArrayList<String>( );
		
		trans.add( "INSERT INTO Resultado VALUES(null,(SELECT ID_EXAMEN FROM Examen WHERE nombre='"+e.getExamen()+"'),"+e.getGeneral()+","+e.getTiempo()+",'"+e.getPais()+"')" );
		
		String t = "INSERT INTO Res_Area VALUES";
		for( String s : e.getAreas() )
			t += "((SELECT LAST_INSERT_ID()),(SELECT ID_AREA FROM Area WHERE nombre='"+s.split(":")[0]+"'),"+s.split(":")[1]+")" + ",";
		
		trans.add( t.substring( 0, t.length()-1 ) );
		
		transaccion( trans );
	}

}
